﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Asset;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Model.FieldMapping;
using FinalPointSet.Model.Model.MockData;
using FinalPointSet.Model.Util;
using FinalPointSet.View.Page.MockData;
using FinalPointSet.ViewModel.Page.MockData;
using ICSharpCode.AvalonEdit.Highlighting;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using static FinalPointSet.Model.Manager.MessageManager;
namespace FinalPointSet.ViewModel.Page.MainView
{
    public partial class MockDataPageViewModel : ObservableObject, IDisposable
    {
        private const int PreviewOutputCount = 7;
        /// <summary>
        /// 模拟数据
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<MockField> _MockFields = [];
        private List<MockField> operateMockFields = [];
        /// <summary>
        /// 脚本资源
        /// </summary>
        [ObservableProperty]
        private List<MockRule> _MockRules = [];
        /// <summary>
        /// 代码高亮
        /// </summary>
        [ObservableProperty]
        private IHighlightingDefinition? _HighlightingDefinition;
        /// <summary>
        /// 显示/隐藏抽屉视图
        /// </summary>
        [ObservableProperty]
        private bool _IsDrawerOpen = false;
        /// <summary>
        /// 输入的字段
        /// </summary>
        [ObservableProperty]
        private string _InputFieldString = string.Empty;
        /// <summary>
        /// 输入的字段
        /// </summary>
        [ObservableProperty]
        private Visibility _Visibility = Visibility.Visible;
        public MockDataPageViewModel()
        {
            InitResource();
            //监听数据源集合资源变化
            AssetManager.Instance.OnJsonObjectListUpdate += OnResourceUpdate;
        }

        /// <summary>
        /// 重新初始化资源
        /// </summary>
        /// <param name="type"></param>
        private void OnResourceUpdate(Type type)
        {
            if (type == typeof(MockRule) || type == typeof(MockFieldMappingRule))
                InitResource();
        }

        /// <summary>
        /// 初始化资源
        /// </summary>
        private void InitResource()
        {
            operateMockFields.Clear();
            MockFields.Clear();
            //初始化脚本资源
            MockRules = AssetManager.Instance.GetJsonObjectList<MockRule>();
            //设置代码高亮
            ObjectPair<IHighlightingDefinition>? hightLightDef = AssetManager.Instance.GetObjectListElementByKey<IHighlightingDefinition>(Path.HighLightDefinition, "SQL");
            if (hightLightDef != null)
            {
                HighlightingDefinition = hightLightDef.Value;
            }
        }

        #region 命令
        /// <summary>
        /// 打开抽屉视图
        /// </summary>
        [RelayCommand]
        private void OpenDrawer()
        {
            IsDrawerOpen = true;
            Visibility = Visibility.Visible;
            Debug.Print($"MockDataPageViewModel.OpenDrawer(), IsDrawerOpen={IsDrawerOpen}");
        }

        /// <summary>
        /// 确认输入字段
        /// </summary>
        [RelayCommand]
        private void ConfirmInput()
        {
            Debug.Print($"MockDataPageViewModel.ConfirmInput()");
            //关闭抽屉视图
            IsDrawerOpen = false;
            //检验输入
            if (string.IsNullOrEmpty(InputFieldString))
            {
                Debug.Print($"MockDataPageViewModel.ConfirmInput(), 输入字段不能为空!");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, $"输入字段不能为空!"));
            }

            try
            {
                //将字符串解析为mock节点
                operateMockFields = ParseFieldString(InputFieldString);
                //更新字段配置表格的数据
                MockFields = new ObservableCollection<MockField>(operateMockFields);
                Debug.Print($"MockDataPageViewModel.ConfirmInput(), 导入字段成功!");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, "导入字段成功!"));
            }
            catch (Exception e)
            {
                Debug.Print($"MockDataPageViewModel.ConfirmInput(), 转换失败! 错误原因:{e.Message}");
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"转换失败! 错误原因:{e.Message}"));
                return;
            }
        }

        /// <summary>
        /// 清空输入字段
        /// </summary>
        [RelayCommand]
        private void ClearInput()
        {
            Debug.Print($"MockDataPageViewModel.ClearInput()");
            InputFieldString = string.Empty;
        }

        /// <summary>
        /// 重置字段映射
        /// </summary>
        [RelayCommand]
        private void Reset()
        {
            Debug.Print($"MockDataPageViewModel.Reset()");
            //将字符串解析为mock节点
            operateMockFields = ParseFieldString(InputFieldString);
            //更新字段配置表格的数据
            MockFields = new ObservableCollection<MockField>(operateMockFields);
        }

        /// <summary>
        /// 生成数据
        /// </summary>
        [RelayCommand]
        private void Generate()
        {
            //校验输入
            if (operateMockFields == null || operateMockFields.Count == 0)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Warning, "请先导入字段数据"));
                return;
            }

            //获取字典的数据
            List<MockRule> MockRules = AssetManager.Instance.GetJsonObjectList<MockRule>();

            try
            {
                //解析
                MockResult previewMockResult = MockParser.Parse(operateMockFields, MockRules, PreviewOutputCount);
                //跳转生成数据配置页面
                PageUtil.Instance.Navigate(PageUtil.MockDataGeneratePage);
                if (PageUtil.Get(typeof(GeneratePage)) is GeneratePage mockDataGeneratePage)
                {
                    if (mockDataGeneratePage.DataContext is GeneratePageViewModel viewModel)
                    {
                        viewModel.Header = previewMockResult.Header;
                        viewModel.FieldDatas = previewMockResult.FieldDatas;
                        viewModel.MockFields = operateMockFields;
                    }
                }
            }
            catch (Exception e)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"转换失败! 错误原因:{e.Message}"));
                return;
            }
        }

        /// <summary>
        /// 设置
        /// </summary>
        [RelayCommand]
        private static void Setting()
        {
            PageUtil.Instance.Navigate(PageUtil.MockDataSettingPage);
        }
        #endregion

        #region 事件&方法
        /// <summary>
        /// 解析字段字符串
        /// </summary>
        /// <param name="strIntputFields"></param>
        private static List<MockField> ParseFieldString(string strFields)
        {
            if (strFields == null || string.Empty.Equals(strFields))
                return [];
            //将传入的字段字符串,解析为字段集合
            List<Field> fields = SQLParser.StringToFields(strFields);
            //读取字典文件
            List<MockRule> MockRules = AssetManager.Instance.GetJsonObjectList<MockRule>();
            List<MockFieldClassify> mockFieldClassifies = AssetManager.Instance.GetJsonObjectList<MockFieldClassify>();
            List<MockFieldMappingRule> mockFieldMappingRules = AssetManager.Instance.GetJsonObjectList<MockFieldMappingRule>();

            //将字段集合转为模拟数据节点集合
            List<MockField> mockFields = MockFieldHelper.ToMockField(fields);

            //识别字段应该调用的脚本
            MockParser.IdentifyFieldMatchScript(mockFields, MockRules, mockFieldClassifies, mockFieldMappingRules);
            return mockFields;
        }

        /// <summary>
        /// 监听模拟数据转换的类型下拉框元素选择变化事件
        /// </summary>
        /// <param name="index">下标</param>
        /// <param name="newCustomScript">新代码</param>
        /// <param name="oldCustomScript">旧代码</param>
        public void OnComboboxSelectionChange(int index, MockRule? newCustomScript, MockRule? oldCustomScript)
        {
            if (newCustomScript == null || oldCustomScript == null || index <= 0)
                return;
            Debug.Print($"MockDataPageViewModel.OnComboboxSelectionChange(), index={index}, oldCustomScript={oldCustomScript.Name}, newCustomScript={newCustomScript.Name}");
            //更新变动的元素
            List<MockField> nodes = [.. MockFields];
            nodes[index - 1].Script = newCustomScript;
            nodes[index - 1].ParamTemplate = newCustomScript.ParamTemplates.Count > 0 ? newCustomScript.ParamTemplates[0] : new();
            nodes[index - 1].Param = nodes[index - 1].ParamTemplate.Value;
            MockFields = new ObservableCollection<MockField>(nodes);
        }

        /// <summary>
        /// 监听模拟数据转换的类型下拉框元素选择变化事件
        /// </summary>
        /// <param name="index">下标</param>
        /// <param name="newCustomScript">新代码</param>
        /// <param name="oldCustomScript">旧代码</param>
        public void OnParamTemplateComboboxSelectionChange(int index, MockParamTemplate? newMPT, MockParamTemplate? oldMPT)
        {
            if (newMPT == null || oldMPT == null || index <= 0)
                return;
            Debug.Print($"MockDataPageViewModel.OnParamTemplateComboboxSelectionChange(), index={index}, newMPT={newMPT.Name}, oldMPT={oldMPT.Name}");
            //更新变动的元素
            List<MockField> nodes = [.. MockFields];
            nodes[index - 1].ParamTemplate = newMPT;
            nodes[index - 1].Param = newMPT.Value;
            MockFields = new ObservableCollection<MockField>(nodes);
        }

        public void Dispose()
        {
            Debug.Print("MockDataPageViewModel.Dispose()");
            AssetManager.Instance.OnJsonObjectListUpdate -= OnResourceUpdate;
            IsDrawerOpen = false;
        }
        #endregion
    }
}
